home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / os2 / raytrace / dkb / os2port.exe / DKB212O2.ZIP / RENDER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-04  |  15.4 KB  |  469 lines

  1. /*****************************************************************************
  2. *
  3. *                                    render.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module implements the main raytracing loop.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     OMX              (613) 731-3419
  37. *     Mystic           (613) 596-4249  or  (613) 596-4772
  38. *
  39. *  Fidonet:   1:163/109.9
  40. *  Internet:  dbuck@ccs.carleton.ca
  41. *  The "You Can Call Me RAY" BBS    (708) 358-5611
  42. *
  43. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  44. *
  45. *     The "You Can Call Me RAY" BBS (708) 358-5611
  46. *     The Information Exchange BBS  (708) 945-5575
  47. *
  48. *****************************************************************************/
  49.  
  50. #include "frame.h"
  51. #include "vector.h"
  52. #include "dkbproto.h"
  53.  
  54.  
  55. #define OS2
  56.  
  57. extern FILE_HANDLE *Output_File_Handle;
  58. extern char Output_File_Name[FILE_NAME_LENGTH];
  59. extern char OutputFormat;
  60. extern int File_Buffer_Size;
  61. extern unsigned int Options;
  62. extern int Quality;
  63. volatile int Stop_Flag;
  64. extern int First_Line, Last_Line;
  65. extern long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  66.  
  67. extern short *hashTable;
  68. extern unsigned short crctab[256];
  69. #define rand3d(a,b) crctab[(int)(hashTable[(int)(hashTable[(int)((a)&0xfff)]^(b))&0xfff])&0xff]
  70.  
  71. FRAME Frame;
  72. RAY *VP_Ray;
  73. int Trace_Level, SuperSampleCount;
  74.  
  75.  
  76. #define MAX_TRACE_LEVEL 5
  77.  
  78. void Output_Line PARAMS((int y, COLOUR **Previous_Line, COLOUR **Current_Line,
  79.   char **Previous_Line_Antialiased_Flags, char **Current_Line_Antialiased_Flags));
  80.  
  81. COLOUR *Previous_Line, *Current_Line;
  82. char *Previous_Line_Antialiased_Flags, *Current_Line_Antialiased_Flags;
  83. RAY Ray;
  84.  
  85. void Create_Ray (ray, width, height, x, y)
  86.    RAY *ray;
  87.    int width, height;
  88.    DBL x, y;
  89.    {
  90.    register DBL X_Scalar, Y_Scalar;
  91.    VECTOR Temp_Vect_1, Temp_Vect_2;
  92.  
  93.    /* Convert the X Coordinate to be a DBL from 0.0 to 1.0 */
  94.    X_Scalar = (x - (DBL) width / 2.0) / (DBL) width;
  95.  
  96.    /* Convert the Y Coordinate to be a DBL from 0.0 to 1.0 */
  97.    Y_Scalar = (( (DBL)(Frame.Screen_Height - 1) - y) -
  98.           (DBL) height / 2.0) / (DBL) height;
  99.  
  100.    VScale (Temp_Vect_1, Frame.View_Point.Up, Y_Scalar);
  101.    VScale (Temp_Vect_2, Frame.View_Point.Right, X_Scalar);
  102.    VAdd (ray->Direction, Temp_Vect_1, Temp_Vect_2);
  103.    VAdd (ray->Direction, ray->Direction, Frame.View_Point.Direction);
  104.    VNormalize (ray->Direction, ray->Direction);
  105.    Initialize_Ray_Containers (ray);
  106.    ray->Quadric_Constants_Cached = FALSE;
  107.    }
  108.  
  109.  
  110. void Supersample (result, x, y, Width, Height)
  111.    COLOUR *result;
  112.    int x, y, Width, Height;
  113.    {
  114.    COLOUR colour;
  115.    register DBL dx, dy, Jitter_X, Jitter_Y;
  116.  
  117.    dx = (DBL) x;
  118.    dy = (DBL) y;
  119.  
  120.    Number_Of_Pixels_Supersampled++;
  121.  
  122.    Make_Colour (result, 0.0, 0.0, 0.0);
  123.  
  124.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  125.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  126.    Create_Ray (VP_Ray, Frame.Screen_Width, Frame.Screen_Height,
  127.              dx + Jitter_X, dy + Jitter_Y);
  128.  
  129.    Trace_Level = 0;
  130.    Trace (VP_Ray, &colour);
  131.    Clip_Colour (&colour, &colour);
  132.    Scale_Colour (&colour, &colour, 0.11111111);
  133.    Add_Colour (result, result, &colour);
  134.  
  135.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  136.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  137.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
  138.                                       dy + Jitter_Y - 0.3333333);
  139.    Trace_Level = 0;
  140.    Trace (VP_Ray, &colour);
  141.    Clip_Colour (&colour, &colour);
  142.    Scale_Colour (&colour, &colour, 0.11111111);
  143.    Add_Colour (result, result, &colour);
  144.  
  145.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  146.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  147.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
  148.                                       dy + Jitter_Y);
  149.    Trace_Level = 0;
  150.    Trace (VP_Ray, &colour);
  151.    Clip_Colour (&colour, &colour);
  152.    Scale_Colour (&colour, &colour, 0.11111111);
  153.    Add_Colour (result, result, &colour);
  154.  
  155.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  156.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  157.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
  158.                                       dy + Jitter_Y + 0.3333333);
  159.    Trace_Level = 0;
  160.    Trace (VP_Ray, &colour);
  161.    Clip_Colour (&colour, &colour);
  162.    Scale_Colour (&colour, &colour, 0.11111111);
  163.    Add_Colour (result, result, &colour);
  164.  
  165.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  166.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  167.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X,
  168.                                       dy + Jitter_Y - 0.3333333);
  169.    Trace_Level = 0;
  170.    Trace (VP_Ray, &colour);
  171.    Clip_Colour (&colour, &colour);
  172.    Scale_Colour (&colour, &colour, 0.11111111);
  173.    Add_Colour (result, result, &colour);
  174.  
  175.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  176.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  177.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X,
  178.                                       dy + Jitter_Y + 0.3333333);
  179.    Trace_Level = 0;
  180.    Trace (VP_Ray, &colour);
  181.    Clip_Colour (&colour, &colour);
  182.    Scale_Colour (&colour, &colour, 0.11111111);
  183.    Add_Colour (result, result, &colour);
  184.  
  185.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  186.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  187.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
  188.                                       dy + Jitter_Y - 0.3333333);
  189.    Trace_Level = 0;
  190.    Trace (VP_Ray, &colour);
  191.    Clip_Colour (&colour, &colour);
  192.    Scale_Colour (&colour, &colour, 0.11111111);
  193.    Add_Colour (result, result, &colour);
  194.  
  195.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  196.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  197.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
  198.                                       dy + Jitter_Y);
  199.    Trace_Level = 0;
  200.    Trace (VP_Ray, &colour);
  201.    Clip_Colour (&colour, &colour);
  202.    Scale_Colour (&colour, &colour, 0.11111111);
  203.    Add_Colour (result, result, &colour);
  204.  
  205.    Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  206.    Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  207.    Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
  208.                                       dy + Jitter_Y + 0.3333333);
  209.    Trace_Level = 0;
  210.    Trace (VP_Ray, &colour);
  211.    Clip_Colour (&colour, &colour);
  212.    Scale_Colour (&colour, &colour, 0.11111111);
  213.    Add_Colour (result, result, &colour);
  214.    }
  215.  
  216. void initialize_renderer()
  217.    {
  218.    allocate_lines(&Previous_Line, &Current_Line, &Previous_Line_Antialiased_Flags, &Current_Line_Antialiased_Flags, &Ray);
  219.    }
  220.  
  221. void Read_Rendered_Part()
  222.    {
  223.    int rc, x, line_number;
  224.    char Red, Green, Blue;
  225.  
  226.    while ((rc = Read_Line(Output_File_Handle, Previous_Line, &line_number)) == 1) {
  227.       if (Options & DISPLAY)
  228.          for (x = 0 ; x < Frame.Screen_Width ; x++) {
  229.             Red = (char) (Previous_Line[x].Red * 255.0);
  230.             Green = (char) (Previous_Line[x].Green * 255.0);
  231.             Blue = (char) (Previous_Line[x].Blue * 255.0);
  232.             display_plot (x, line_number, Red, Green, Blue);
  233.             }
  234.       }
  235.  
  236.    First_Line = line_number+1;
  237.  
  238.    if (rc == 0) {
  239.       Close_File(Output_File_Handle);
  240.       if (Open_File (Output_File_Handle, Output_File_Name,
  241.               &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  242.               APPEND_MODE) != 1) {
  243.          fprintf (stderr, "Error opening output file\n");
  244.          exit(1);
  245.          }
  246.       return;
  247.       }
  248.  
  249.    fprintf (stderr, "Error reading aborted data file\n");
  250.    }
  251.  
  252. void Start_Tracing ()
  253.    {
  254.    COLOUR Colour;
  255.    register int x, y;
  256.    char Red, Green, Blue, Antialias_Center_Flag;
  257.  
  258.    for (y = (Options & ANTIALIAS)?First_Line-1:First_Line; y<Last_Line; y++) {
  259.  
  260.       check_stats(y);
  261. #ifdef OS2
  262.       
  263.       /* display where we are: */
  264.       printf("Processing line: %u\r",y); 
  265. #endif
  266.       for (x = 0 ; x < Frame.Screen_Width ; x++) {
  267.          Number_Of_Pixels++;
  268.          if (Stop_Flag) {
  269.             close_all();
  270.             exit(0);
  271.             }
  272.  
  273.          TEST_ABORT
  274.  
  275.          Create_Ray (VP_Ray, Frame.Screen_Width, Frame.Screen_Height, (DBL) x, (DBL) y);
  276.          Trace_Level = 0;
  277.          Trace (&Ray, &Colour);
  278.          Clip_Colour (&Colour, &Colour);
  279.  
  280.          Current_Line[x] = Colour;
  281.  
  282.          if (Options & ANTIALIAS) {
  283.             Antialias_Center_Flag = 0;
  284.             Current_Line_Antialiased_Flags[x] = 0;
  285.  
  286.             if (x != 0) {
  287.                if (Colour_Distance (&Current_Line[x-1], &Current_Line[x])
  288.                    >= Frame.Antialias_Threshold) {
  289.                   Antialias_Center_Flag = 1;
  290.                   if (!(Current_Line_Antialiased_Flags[x-1])) {
  291.                      Supersample (&Current_Line[x-1], 
  292.                                   x-1, y, Frame.Screen_Width, Frame.Screen_Height);
  293.                      Current_Line_Antialiased_Flags[x-1] = 1;
  294.                      SuperSampleCount++;
  295.                      }
  296.                   }
  297.                }
  298.  
  299.             if (y != First_Line-1) {
  300.                if (Colour_Distance (&Previous_Line[x], &Current_Line[x])
  301.                     >= Frame.Antialias_Threshold) {
  302.                   Antialias_Center_Flag = 1;
  303.                   if (!(Previous_Line_Antialiased_Flags[x])) {
  304.                      Supersample (&Previous_Line[x],
  305.                                   x, y-1, Frame.Screen_Width, Frame.Screen_Height);
  306.                      Previous_Line_Antialiased_Flags[x] = 1;
  307.                      SuperSampleCount++;
  308.                      }
  309.                   }
  310.                }
  311.  
  312.             if (Antialias_Center_Flag) {
  313.                Supersample (&Current_Line[x],
  314.                             x, y, Frame.Screen_Width, Frame.Screen_Height);
  315.                Current_Line_Antialiased_Flags[x] = 1;
  316.                Colour = Current_Line[x];
  317.                SuperSampleCount++;
  318.                }
  319.             }
  320.  
  321.          if (y != First_Line-1) {
  322.             Red = (char) (Colour.Red * 255.0);
  323.             Green = (char) (Colour.Green * 255.0);
  324.             Blue = (char) (Colour.Blue * 255.0);
  325.  
  326.             if (Options & DISPLAY)
  327.                display_plot (x, y, Red, Green, Blue);
  328.             }
  329.          }
  330.       Output_Line(y, &Previous_Line, &Current_Line, &Previous_Line_Antialiased_Flags, &Current_Line_Antialiased_Flags);
  331.       }
  332.  
  333.    if (Options & DISKWRITE) {
  334.       Write_Line (Output_File_Handle, Previous_Line, Last_Line - 1);
  335.       }
  336.    }
  337.  
  338. void check_stats(y)
  339.    register int y;
  340.    {
  341.       if (Options & VERBOSE)
  342.          printf ("Line %3d", y);
  343.  
  344.       if (Options & ANTIALIAS)
  345.          SuperSampleCount = 0;
  346.    }
  347.  
  348. void  allocate_lines(Previous_Line, Current_Line, Previous_Line_Antialiased_Flags, Current_Line_Antialiased_Flags, Ray)
  349.    COLOUR **Previous_Line, **Current_Line;
  350.    char **Previous_Line_Antialiased_Flags, **Current_Line_Antialiased_Flags;
  351.    RAY *Ray;
  352.    {
  353.    register int i;
  354.  
  355.    VP_Ray = Ray;
  356.  
  357.    *Previous_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  358.    *Current_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  359.  
  360.    for (i = 0 ; i <= Frame.Screen_Width ; i++) {
  361.       (*Previous_Line)[i].Red = 0.0;
  362.       (*Previous_Line)[i].Green = 0.0;
  363.       (*Previous_Line)[i].Blue = 0.0;
  364.  
  365.       (*Current_Line)[i].Red = 0.0;
  366.       (*Current_Line)[i].Green = 0.0;
  367.       (*Current_Line)[i].Blue = 0.0;
  368.       }
  369.  
  370.    if (Options & ANTIALIAS) {
  371.       *Previous_Line_Antialiased_Flags =
  372.           (char *) malloc (sizeof (char)*(Frame.Screen_Width + 1));
  373.       *Current_Line_Antialiased_Flags =
  374.           (char *)  malloc (sizeof (char)*(Frame.Screen_Width + 1));
  375.  
  376.       for (i = 0 ; i <= Frame.Screen_Width ; i++) {
  377.          (*Previous_Line_Antialiased_Flags)[i] = 0;
  378.          (*Current_Line_Antialiased_Flags)[i] = 0;
  379.          }
  380.    }
  381.  
  382.    Ray->Initial = Frame.View_Point.Location;
  383.    return;
  384.    }
  385.  
  386. void Output_Line (y, Previous_Line, Current_Line, Previous_Line_Antialiased_Flags, Current_Line_Antialiased_Flags)
  387.    register int y;
  388.    COLOUR **Previous_Line, **Current_Line;
  389.    char **Previous_Line_Antialiased_Flags, **Current_Line_Antialiased_Flags;
  390.    {
  391.       COLOUR *Temp_Colour_Ptr;
  392.       char *Temp_Char_Ptr;
  393.  
  394.       if (Options & DISKWRITE)
  395.          if (y > First_Line) {
  396.             Write_Line (Output_File_Handle, *Previous_Line, y-1);
  397.          }
  398.  
  399.       if (Options & VERBOSE)
  400.          if (Options & ANTIALIAS)
  401.             printf (" supersampled %d times\n", SuperSampleCount);
  402.          else
  403.             putchar ('\n');
  404.  
  405.       Temp_Colour_Ptr = *Previous_Line;
  406.       *Previous_Line = *Current_Line;
  407.       *Current_Line = Temp_Colour_Ptr;
  408.  
  409.       Temp_Char_Ptr = *Previous_Line_Antialiased_Flags;
  410.       *Previous_Line_Antialiased_Flags = *Current_Line_Antialiased_Flags;
  411.       *Current_Line_Antialiased_Flags = Temp_Char_Ptr;
  412.  
  413.       return;
  414.    }
  415.  
  416. void Trace (Ray, Colour)
  417.    RAY *Ray;
  418.    COLOUR *Colour;
  419.    {
  420.    OBJECT *Object;
  421.    INTERSECTION *Local_Intersection, *New_Intersection;
  422.    register int Intersection_Found;
  423.  
  424.    Number_Of_Rays++;
  425.    Make_Colour (Colour, 0.0, 0.0, 0.0);
  426.  
  427.    Intersection_Found = FALSE;
  428.    Local_Intersection = NULL;
  429.  
  430.    if (Trace_Level > MAX_TRACE_LEVEL) {
  431.       return;
  432.       }
  433.  
  434.    if (Frame.Fog_Distance == 0.0) {
  435.       Make_Colour (Colour, 0.0, 0.0, 0.0);
  436.       }
  437.    else
  438.       *Colour = Frame.Fog_Colour;
  439.  
  440.    if (Options & DEBUGGING)
  441.       printf ("Calculating intersections level %d\n", Trace_Level);
  442.  
  443.     /* What objects does this ray intersect? */
  444.    for (Object = Frame.Objects ; 
  445.         Object != NULL ;
  446.         Object = Object -> Next_Object) {
  447.  
  448.       if (New_Intersection = Intersection (Object, Ray)) {
  449.          if (Intersection_Found) {
  450.             if (Local_Intersection -> Depth > New_Intersection -> Depth) {
  451.                free (Local_Intersection);
  452.                Local_Intersection = New_Intersection;
  453.                }
  454.             else
  455.                free (New_Intersection);
  456.             }
  457.          else
  458.             Local_Intersection = New_Intersection;
  459.  
  460.          Intersection_Found = TRUE;
  461.          }
  462.       }
  463.  
  464.    if (Intersection_Found) {
  465.       Determine_Surface_Colour (Local_Intersection, Colour, Ray, FALSE);
  466.       free (Local_Intersection);
  467.       }
  468.    }
  469.